package com.guigu.tomcat.impl;

import com.guigu.tomcat.*;

import java.io.IOException;
import java.io.InputStream;


import java.net.Socket;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

public class HttpServletRequestImpl implements HttpServletRequest {

    private final InputStream in;
    private Socket socket;
    private final String method;
    private final String requestURI;
    private final String protocol;
    private Map<String,String> paramsMap=new LinkedHashMap<>();

    private Map<String, String> headerMap = new LinkedHashMap<>();

//    private Socket socket;

    @Override
    public String toString() {
        return method;
    }

    public HttpServletRequestImpl(Socket socket) throws IOException {
        this.socket = socket;
        this.in = socket.getInputStream();
        String line = readLine(in);
        //解析头行
        String[] items = line.split(" ");
        this.method = items[0];
        this.requestURI = items[1];
        this.protocol = items[2];

        String paramStr = this.requestURI.replaceAll("[^\\?#]+(\\?(.+))?(#.+)?","$2");
        if(paramStr!=null & paramStr.length()>0){
            items = paramStr.split("&");
            for (String item : items) {
                String[] nameAndValue =item.split("=");
                //如果参数编码 汉字==》utf-8 == > 解码
                nameAndValue[0] =URLDecoder.decode(nameAndValue[0],"utf-8");
                nameAndValue[1] =URLDecoder.decode(nameAndValue[1],"utf-8");
             paramsMap.put(nameAndValue[0],nameAndValue[1]);
            }
        }
        //一直读取直到遇到空行
        //赋值语句外加括号来获取返回值
        while ((line = readLine(in)).isEmpty() == false) {
            items = line.split(":");
            headerMap.put(items[0], items[1]);

        }
        //TODO body(正文暂不处理)
        //post 请求参数:method=post,content-type:表单，文件上传，length
        //获取正文长度 Content-Length
        /*
        Content-Length :正文的大小
        正文的内容类型application/x-www-form-urlencoded表单类型
        muLtipart/form-data 文件上传
        Cotent-Type:application/x-www-form-urlencoded==>默认类型
        Content-Type: multipart/form-data; boundary=---------------------------57121323410575192283721952287
        boundary 分割上传的多次参数

        上传文件处理策略
        1，如果没有超过界限直接处理保存在内存中封装成对象Part。write(本地文件)
        2.如果文件超过界限则将文件保存为临时的磁盘文件
        3，因此servlet对文件上传大小，临界文件边界大小，临时文件都有设置
         */

        if("POST".equals(method)){
            String length = headerMap.get("Content-Length");
            length.replaceAll(" ","");
            int iLength = Integer.parseInt(length.trim());
            byte[] bytes =new byte[iLength];
            int count;
             InputStream in = socket.getInputStream();
             //一次性读入全部数据
            in.read(bytes,0,iLength);
            System.out.println(new String(bytes,0,iLength));
        }
    }

    private String readLine(InputStream in) throws IOException {

        StringBuilder line = new StringBuilder();
        char c;
        while (true) {
            c = (char) in.read();//一次读入一个字符
            //window系统的换行是\r回车\n换行
            if (c == '\r') {
                in.read();//读到\n
                System.out.println(line);
                return line.toString();

            } else {
                line.append(c);
            }

        }

    }


    @Override
    public InputStream getInputStream() {
        return null;
    }

    @Override
    public String getMethod() {
        return method;
    }

    @Override
    public String getRequestURI() {
        return requestURI;
    }

    @Override
    public String getProtocol() {
        return protocol;
    }

    @Override
    public String getHeader(String name) {
        return headerMap.get(name);
    }

    @Override
    public Cookie[] getCookies() {
        String cookies = headerMap.get("Cookie");
        if(cookies==null){
            return null;
        }
        String[] splits = cookies.split(";\\s");
        Cookie[]cookieObjs = new Cookie[splits.length];
        for (int i = 0; i < splits.length; i++) {
            String split =splits[i];
            String[] nameAndValues = split.split("=");
            //如果有非西方字符，请解码
            cookieObjs[i] =  new CookieImpl(nameAndValues[0],nameAndValues[1]);
        }
        return cookieObjs;
    }

    @Override
    public String getRequestedSessionId() {
        return null;
    }

    //会话容器 一般写在Tomcat类里
    private  static Map<String,HttpSession> sessionMap = new HashMap<>();

    @Override
    public HttpSession getSession() {
        /**
         * 容器没有会话对象的额情况：
         * 1，第一次访问是时间
         * 2。会话超时超过三十分钟
         * 3，手动执行invalidate手动超时对应用户退出登录后台调用invalidate
         * 4，会话机制被打破
         * 1）cookie存放会话ID 默认
         *    1,将会话id发送给浏览器 JSESSIONID=xxxx
         *    2,从cookie获取会话id提取会话对象
         *    2）地址栏保持会话ID
         *    3）隐藏域保存会话ID
         */



        //从cookie中查找会话id
        Cookie[] cookies = this.getCookies();
        String sessionId =null;
        if(cookies!=null){
            for (Cookie cookie : cookies) {
                if(cookie.getName().equals("JSESSIONID")){
                    sessionId = cookie.getValue();
                    break;
                }
            }
        }
        HttpSession httpSession = sessionMap.get("sessionId");
        //如果容器中没有浏览器的会话对象就创建一个
        if(httpSession==null){
            httpSession = new HttpSessionImpl();
            sessionMap.put(httpSession.getId(),httpSession);
        }
        return httpSession;
    }

    @Override
    public String getParameter(String name) {
        return paramsMap.get(name);
    }

    @Override
    public String[] getParameterValues(String name) {
        return new String[0];
    }

    @Override
    public String getQueryString() {
        return null;
    }

    @Override
    public void getSession(HttpSession session) {

    }
}
